package com.itkjb.leisurely.center.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itkjb.leisurely.center.common.CenterConstants;
import com.itkjb.leisurely.center.sys.mapper.SysUserMapper;
import com.itkjb.leisurely.center.sys.model.SysUserDetail;
import com.itkjb.leisurely.center.sys.model.SysUserModel;
import com.itkjb.leisurely.center.sys.service.ISysUserService;
import com.itkjb.leisurely.core.base.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author itkjb.com
 * @since 2020-07-22
 */
@Service
@Slf4j
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUserModel> implements ISysUserService  {

    @Autowired
    PasswordEncoder passwordEncoder;

    public SysUserModel getUserByLogin(Serializable param, CenterConstants.LoginType loginType){
        SysUserModel user = null;
        if(param == null || "".equals(param.toString().trim()) || loginType ==null){
            return user;
        }
        QueryWrapper<SysUserModel> wrapper = new QueryWrapper<>();
        if(loginType == CenterConstants.LoginType.username){
            wrapper.lambda().eq(SysUserModel::getUsername,param);
        }else if(loginType == CenterConstants.LoginType.mobile){
            wrapper.lambda().eq(SysUserModel::getMobile,param);
        }else if(loginType == CenterConstants.LoginType.email){
            wrapper.lambda().eq(SysUserModel::getEmail,param);
        }else if(loginType == CenterConstants.LoginType.id){
            wrapper.lambda().eq(SysUserModel::getId,param);
        }
        user = this.baseMapper.selectOne(wrapper);
        return user;
    }
    /**
     * wrapper 组装器，构造条件查询
     * @author itkjb.com
     * @date  2020-07-22
     * @param wrapper
     * @param model 条件
     **/
    @Override
    protected void assembleWrapper(QueryWrapper<SysUserModel> wrapper, SysUserModel model) {
        // （代码生成器生成）自动生成了，list查询的时候，条件组装，开发者自行删除不需要的条件
        // 用户名
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getUsername()), SysUserModel::getUsername, model.getUsername() );
        // 密码
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getPassword()), SysUserModel::getPassword, model.getPassword() );
        // 手机号
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getMobile()), SysUserModel::getMobile, model.getMobile() );
        // 邮箱
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getEmail()), SysUserModel::getEmail, model.getEmail() );
        // 显示的名字
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getNickname()), SysUserModel::getNickname, model.getNickname() );
        // 创建类型 1：后台添加 ，0: 用户注册
        wrapper.lambda().eq(model.getCreateType() != null, SysUserModel::getCreateType, model.getCreateType() );
        // 默认组织id
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getDefDepid()), SysUserModel::getDefDepid, model.getDefDepid() );
        // 最后登陆时间
        wrapper.lambda().eq(model.getLastLogin() != null, SysUserModel::getLastLogin, model.getLastLogin() );
        // 最后一次登陆ip
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getLastIp()), SysUserModel::getLastIp, model.getLastIp() );
        // 最后一次登录ip地址描述
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getLastIpDes()), SysUserModel::getLastIpDes, model.getLastIpDes() );
        // 状态 1 创建，注册；2：待完善信息 ；4：待补充调整信息  8：正常 16：账户冻结
        wrapper.lambda().eq(model.getStatus() != null, SysUserModel::getStatus, model.getStatus() );
    }




    /**
     * wrapper 组装器，组装list查询时，查询的列
     * @author itkjb.com
     * @date  2020-07-22
     * @param wrapper
     * @param model
     * @return void
     * @since 2020-07-22
     **/
    @Override
    protected void buildListSelectColumns(QueryWrapper<SysUserModel> wrapper, SysUserModel model){
        buildCommonSelectColumns(wrapper, model);
    }

    /**
     * 组装列表查询的列（字段）
     * @date  2020-07-22
     * @param wrapper
     * @param model
     */
    protected void buildCommonSelectColumns(QueryWrapper<SysUserModel> wrapper, SysUserModel model){
        // 代码生成器生成，为了简化开发时，查询list时，查询指定字段，没必要查询所有参数
        wrapper.lambda().select(
            // id
            SysUserModel::getId,
            // 用户名
            SysUserModel::getUsername,
            // 密码
            SysUserModel::getPassword,
            // 手机号
            SysUserModel::getMobile,
            // 邮箱
            SysUserModel::getEmail,
            // 显示的名字
            SysUserModel::getNickname,
            // 创建类型 1：后台添加 ，0: 用户注册
            SysUserModel::getCreateType,
            // 默认组织id
            SysUserModel::getDefDepid,
            // 最后登陆时间
            SysUserModel::getLastLogin,
            // 最后一次登陆ip
            SysUserModel::getLastIp,
            // 最后一次登录ip地址描述
            SysUserModel::getLastIpDes,
            // 状态 1 创建，注册；2：待完善信息 ；4：待补充调整信息  8：正常 16：账户冻结
            SysUserModel::getStatus,
            SysUserModel::getCreateTime
        );
    }

    /**
     * 用户登录
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    // @LeisurelyRequestLog(value = "用户名密码登陆",paramsName = "username",recordResult = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUserModel sysUserModel = this.getUserByLogin(username,CenterConstants.LoginType.username);
        SysUserDetail user = null;
        if(sysUserModel ==null){
            throw new UsernameNotFoundException(username);
        }else{
            //权限组装
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            user =new SysUserDetail(sysUserModel.getUsername(), sysUserModel.getPassword(),
                    // 参数要求（账户可用），账户是否可用,没有删除，即可用
                    !sysUserModel.getIsDel()  ,
                    // 参数要求（账户没有过期）， 账户是否过期，删除即过期
                    !sysUserModel.getIsDel(),
                    // 参数要求（账户授权没有过期），非正常状态，和锁定状态，此种状态可为 带审核
                    sysUserModel.getStatus()==8 || sysUserModel.getStatus() == 16 ,
                    // 参数要求（账户没有被锁定）， 账户是否锁定
                    sysUserModel.getStatus() != 16,
                    grantedAuthorities);
            user.setUserId(sysUserModel.getId());
        }
        return  user;
    }

    @Override
    public int updateLastLoginInfo(SysUserModel user) {
        SysUserModel userModel = new SysUserModel();
        userModel.setId(user.getId());
        userModel.setLastIp(user.getLastIp());
        userModel.setLastLogin(new Date());
        userModel.setLastIpDes(user.getLastIpDes());
        // 为了解决更新时会将updateuser 信息置空的问题
        user = this.baseMapper.selectById(user.getId());
        userModel.setUpdateUserId(user.getUpdateUserId());
        userModel.setUpdateUserName(user.getUpdateUserName());
        return this.baseMapper.updateById(userModel);
    }
}
